﻿
Imports std
Imports centrosphere
Imports jobworker_lock_t = lockWrapper(Of locks.monitorlock)

Partial Public Class storageJobConsumer
    Private Overloads Shared Function workon(Of T)(ByVal j As storageJob,
                                                   ByVal d As _do(Of pointer(Of T), eventComb),
                                                   ByVal f As void(Of T),
                                                   ByVal l As jobworker_lock_t) As eventComb
        assert(Not j Is Nothing)
        assert(Not d Is Nothing)
        assert(Not f Is Nothing)

        Dim p As pointer(Of T) = Nothing
        Dim ec As eventComb = Nothing
        Return New eventComb(Function() As Boolean
                                 Dim dec As eventComb = Nothing
                                 ec = New eventComb(Function() As Boolean
                                                        p = New pointer(Of T)()
                                                        dec = d(p)
                                                        assert(Not dec Is Nothing)
                                                        Return waitfor(dec) AndAlso
                                                               goto_next()
                                                    End Function,
                                                    Function() As Boolean
                                                        If dec.end_result() Then
                                                            If Not l Is Nothing Then
                                                                l.wait()
                                                            End If
                                                            Try
                                                                f(+p)
                                                            Finally
                                                                If Not l Is Nothing Then
                                                                    l.release()
                                                                End If
                                                            End Try
                                                            Return goto_end()
                                                        Else
                                                            Return False
                                                        End If
                                                    End Function)
                                 Return waitfor(ec) AndAlso
                                        goto_next()
                             End Function,
                             Function() As Boolean
                                 If ec.end_result() Then
                                     Return goto_end()
                                 Else
                                     j.result = False
                                     Return False
                                 End If
                             End Function)
    End Function

    Private Overloads Shared Function workon(ByVal j As storageJob,
                                             ByVal d As _do(Of pointer(Of Boolean), eventComb),
                                             ByVal l As jobworker_lock_t) As eventComb
        assert(Not j Is Nothing)
        Return workon(j,
                      d,
                      Sub(ByRef i As Boolean)
                          If Not i Then
                              j.result = False
                          End If
                      End Sub,
                      l)
    End Function

    Private Overloads Shared Function workon(ByVal j As storageJob,
                                             ByVal d As _do(Of pointer(Of Int64), eventComb),
                                             ByVal l As jobworker_lock_t) As eventComb
        assert(Not j Is Nothing)
        Return workon(j,
                      d,
                      Sub(ByRef i As Int64)
                          If i < 0 Then
                              j.result = False
                          Else
                              j.i64 += i
                          End If
                      End Sub,
                      l)
    End Function

    Private Shared Function write(ByVal s As islice,
                                  ByVal j As storageJob,
                                  ByVal l As jobworker_lock_t) As eventComb
        Return workOn(j,
                      Function(ByRef p) s.write(j.key, j.buff, j.i64, p),
                      l)
    End Function

    Private Shared Function uniqueWrite(ByVal s As islice,
                                        ByVal j As storageJob,
                                        ByVal l As jobworker_lock_t) As eventComb
        Return workOn(j,
                      Function(ByRef p) s.uniqueWrite(j.key, j.buff, j.i64, p),
                      l)
    End Function

    Private Shared Function delete(ByVal s As islice,
                                   ByVal j As storageJob,
                                   ByVal l As jobworker_lock_t) As eventComb
        Return workOn(j,
                      Function(ByRef p) s.delete(j.key, p),
                      l)
    End Function

    Private Shared Function modify(ByVal s As islice,
                                   ByVal j As storageJob,
                                   ByVal l As jobworker_lock_t) As eventComb
        Return workOn(j,
                      Function(ByRef p) s.modify(j.key, j.buff, j.i64, p),
                      l)
    End Function

    Private Shared Function read(ByVal s As islice,
                                 ByVal j As storageJob,
                                 ByVal l As jobworker_lock_t) As eventComb
        Dim pi As pointer(Of Int64) = Nothing
        pi = New pointer(Of Int64)()
        Return workOn(j,
                      Function(ByRef p) s.read(j.key, p, pi),
                      Sub(ByRef i As bytes)
                          If i Is Nothing OrElse (+pi) <= 0 Then
                              j.result = False
                          Else
                              j.buff += i
                              If j.i64 < (+pi) Then
                                  j.i64 = (+pi)
                              End If
                          End If
                      End Sub,
                      l)
    End Function

    Private Shared Function seek(ByVal s As islice,
                                 ByVal j As storageJob,
                                 ByVal l As jobworker_lock_t) As eventComb
        Return workOn(j,
                      Function(ByRef p) s.seek(j.key, p),
                      l)
    End Function

    Private Shared Function capacity(ByVal s As islice,
                                     ByVal j As storageJob,
                                     ByVal l As jobworker_lock_t) As eventComb
        Return workOn(j,
                      Function(ByRef p) s.capacity(p),
                      l)
    End Function

    Private Shared Function valuesize(ByVal s As islice,
                                      ByVal j As storageJob,
                                      ByVal l As jobworker_lock_t) As eventComb
        Return workOn(j,
                      Function(ByRef p) s.valuesize(p),
                      l)
    End Function

    Private Shared Function list(ByVal s As islice,
                                 ByVal j As storageJob,
                                 ByVal l As jobworker_lock_t) As eventComb
        Return workOn(j,
                      Function(ByRef p) s.list(p),
                      Sub(ByRef i As vector(Of String))
                          If i Is Nothing Then
                              j.result = False
                          Else
                              j.vs.push_back(i)
                          End If
                      End Sub,
                      l)
    End Function

    Private Shared Function status(ByVal s As islice,
                                   ByVal j As storageJob,
                                   ByVal l As jobworker_lock_t) As eventComb
        Return New eventComb(Function() As Boolean
                                 l.wait()
                                 j.i64 += 1
                                 Dim sw As unhealth_slice_wrapper = Nothing
                                 If convertor.cast(Of unhealth_slice_wrapper)(s, sw) AndAlso
                                    sw.unhealth() Then
                                     j.i64_2 += 1
                                 End If
                                 l.release()
                                 Return goto_end()
                             End Function)
    End Function

    Private Shared Function full(ByVal s As islice,
                                 ByVal j As storageJob,
                                 ByVal l As jobworker_lock_t) As eventComb
        Return workOn(j,
                      Function(ByRef p) s.full(p),
                      l)
    End Function

    Private Shared Function retire(ByVal s As islice,
                              ByVal j As storageJob,
                              ByVal l As jobworker_lock_t) As eventComb
        Return workOn(j,
                      Function(ByRef p) s.retire(p),
                      l)
    End Function

    Private Shared Function empty(ByVal s As islice,
                                  ByVal j As storageJob,
                                  ByVal l As jobworker_lock_t) As eventComb
        Return workOn(j,
                      Function(ByRef p) s.empty(p),
                      l)
    End Function

    Private Shared Function sizeof(ByVal s As islice,
                              ByVal j As storageJob,
                              ByVal l As jobworker_lock_t) As eventComb
        Return workOn(j,
                      Function(ByRef p) s.sizeof(j.key, p),
                      l)
    End Function

    Private Shared Function keycount(ByVal s As islice,
                                     ByVal j As storageJob,
                                     ByVal l As jobworker_lock_t) As eventComb
        Return workOn(j,
                      Function(ByRef p) s.keycount(p),
                      l)
    End Function
End Class
